package cn.anc.httpcontrolutil;

import android.net.Network;
import android.os.Build;
import android.util.Log;

import java.io.Closeable;
import java.io.FileDescriptor;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.Socket;

/**
 * Created by baobaoding on 2017/12/24.
 */

public class SocketUtils {
    private static String TAG = SocketUtils.class.getSimpleName();
    public static Network mobileNetwork, wifiNetwork;

    public static void setMobileNetWork(Network network) {
        mobileNetwork = network;
    }

    public static void setWifiNetwork(Network network) {
        wifiNetwork = network;
    }

    private static int bindSocketToNetwork(int socketfd, Network network) {
        if (network == null) {
            return -1;
        }
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            return -1;
        }
        Log.d(TAG, "start bindSocketToNetwork");
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            FileDescriptor fileDescriptor = new FileDescriptor();
            try {
                Field field = FileDescriptor.class.getDeclaredField("descriptor");
                field.setAccessible(true);
                field.setInt(fileDescriptor, socketfd);
                network.bindSocket(fileDescriptor);
                Log.d(TAG, "bindSocketToNetwork success: network" + network + "+socketfd" + socketfd);
                return 0;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return -1;
    }

    private static int bindSocketToNetwork(Socket socket, Network network) {
        if (network == null) {
            return -1;
        }
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            return -1;
        }
        try {
            network.bindSocket(socket);
            return 0;
        } catch (Exception ex) {
            Log.e(TAG, "--------------------------------failed to bind Socket to Net error is :" + ex.getMessage());
        }
        return -1;
    }

    public static int bindSocketToMobileNetwork(int socketfd) {
        return bindSocketToNetwork(socketfd, mobileNetwork);
    }

    public static int bindSocketToWifiNetwork(int socketfd) {
        return bindSocketToNetwork(socketfd, wifiNetwork);
    }

    public static int bindSocketToMobileNetwork(Socket socket) {
        return bindSocketToNetwork(socket, mobileNetwork);
    }

    public static int bindSocketToWifiNetwork(Socket socket) {
        return bindSocketToNetwork(socket, wifiNetwork);
    }


    public static void closeResources(Closeable... resources) {
        for (Closeable resource : resources) {
            try {
                resource.close();
            } catch (IOException e) {
                // Ignore
            }
        }
    }
}
